package cn.fl.dk.web.service.impl;

import cmm.mid.core.framework.page.KeyValueVO;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.*;
import cn.fl.capital.dto.CapOverdueInfoDTO;
import cn.fl.capital.service.ICapOverdueInfoApiService;
import cn.fl.dk.facade.api.IDkQuestneLogApiService;
import cn.fl.dk.facade.constant.DkQuestneLogConstant;
import cn.fl.dk.facade.dto.DkQuestneLogDTO;
import cn.fl.dk.web.service.calculator.ScoreCalculator;
import cn.fl.dk.web.service.IDkBillDtlService;
import cn.fl.dk.web.service.ITemplateService;
import cn.fl.dk.web.vo.*;
import cn.fl.project.dto.PrjPrdDtlDTO;
import cn.fl.project.service.IProjectApiService;
import cn.fl.ref.fncprjbscinfo.util.DateUtil;
import cn.fl.system.vo.SysScoreDtlRecVO;
import cn.fl.system.vo.SysScoreRecVO;
import com.alibaba.fastjson.JSON;
import fl.score.mgt.facade.score.score.api.*;
import fl.score.mgt.facade.score.score.condition.*;
import fl.score.mgt.facade.score.score.dto.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 作者:hongyanbo
 * 时间:2018/6/4
 */
@Service
public class TemplateServiceImpl implements ITemplateService ,ApplicationContextAware{
    public static final Logger LOG = LoggerFactory.getLogger(TemplateServiceImpl.class);

    private ApplicationContext applicationContext ;
    /**
     * 模板服务
     */
    @Autowired
    private ISysScoreTmplQueryApiService tmplQueryApiService;
    /**
     * 问题服务
     */
    @Autowired
    private ISysScoreIdxQueryApiService idxQueryApiService;
    /**
     * 问卷服务
     */
    @Autowired
    private IDkQuestneLogApiService questneLogApiService ;
    /**
     * 选项服务
     */
    @Autowired
    private ISysScoreIdxOptQueryApiService optQueryApiService;
    /**
     * 逾期服务
     */
    @Autowired
    private ICapOverdueInfoApiService capOverdueInfoApiService;
    /**
     * 产品服务
     */
    @Autowired
    private IProjectApiService projectApiService ;
    /**
     * 评分记录add
     */
    @Autowired
    private ISysScoreRecAddApiService recAddApiService;
    /**
     * 评分记录query
     */
    @Autowired
    private ISysScoreRecQueryApiService recQueryApiService ;
    /**
     * 评分记录modify
     */
    @Autowired
    private ISysScoreRecModifyApiService recModifyApiService;
    /**
     * 评分记录明细add
     */
    @Autowired
    private ISysScoreDtlRecAddApiService dtlRecAddApiService;
    /**
     * 评分记录明细 modify
     */
    @Autowired
    private ISysScoreDtlRecModifyApiService dtlRecModifyApiService;
    /**
     * 评分记录明细query
     */
    @Autowired
    private ISysScoreDtlRecQueryApiService dtlRecQueryApiService;
    @Autowired
    private ISysScoreDtlRecDeleteApiService dtlRecDeleteApiService;
    /**
     * 垫款单明细
     */
    @Autowired
    private IDkBillDtlService billDtlService;
    /**
     * 题目关系
     */
    @Autowired
    private ISysScoreIdxOptRlQueryApiService rlQueryApiService;
    @Resource(name="examBScoreCalculator")
    private ScoreCalculator examBScoreCalculator;
    @Resource(name="examAScoreCalculator")
    private ScoreCalculator examAScoreCalculator;


    @Override
    public TemplateVO getTemplate(String templateId ,String questneId) {
        if(StringUtils.isBlank(templateId) || StringUtils.isBlank(questneId)){
            BaseLogUtils.error(LOG,"getTemplate","调用参数不完整返回null 1:"+templateId+"2:"+questneId);
            return null;
        }
        TemplateVO result = new TemplateVO();
        // getTemplateByID
        SysScoreTmplDTO dto = tmplQueryApiService.getById(templateId);
        // 填充TemplateVO 其他字段
        if(dto!=null){
            result.setId(String.valueOf(dto.getId()));
            result.setName(dto.getTmplNm());
            result.setTemplateCd(dto.getTmplCd());
            // 查问卷表
            DkQuestneLogDTO dkQuestneLogDTO = this.questneLogApiService.selectById(questneId);
            if(dkQuestneLogDTO!=null){
                result.setRuleFlag(dkQuestneLogDTO.getRuleFlag());
                result.setStatus(dkQuestneLogDTO.getQtnStsCd());
                result.setPersonNm(dkQuestneLogDTO.getCstMgrNm());
                result.setDate(DateUtils.formatDateToString(dkQuestneLogDTO.getCrtTm(),DateUtils.YYYY_MM_DD));
                result.setResult(parseDkRstDic(dkQuestneLogDTO.getQtnRstCd()));
                result.setQtnType(dkQuestneLogDTO.getQtnType());//试卷类型  已出险/未出险问卷
                DkBillDtlVO dkBillDtlVO = billDtlService.selectByRuleFlag(dkQuestneLogDTO.getRuleFlag());
                if(dkBillDtlVO!=null){
                    //  查询垫款明细
                    result.setPaySchNo(dkBillDtlVO.getPaySchNo());
                    //  项目名称 支付表No
                    PrjPrdDtlDTO prjPrdDtlDTO = this.projectApiService.selectPrjPrdDtlByPaySchId(String.valueOf(dkBillDtlVO.getPaySchId()));
                    if(prjPrdDtlDTO!=null ){
                        result.setPrjNm(prjPrdDtlDTO.getPrdNm());
                    }
                    // 查询 逾期日期，逾期金额，逾期罚息
                    CapOverdueInfoDTO capOverdueInfoDTO = capOverdueInfoApiService.selectByPaySchNo(dkBillDtlVO.getPaySchNo());
                    if(capOverdueInfoDTO!=null ){

                        result.setOvdDay(String.valueOf(capOverdueInfoDTO.getOverdueDay()));
                        result.setOvdAmount(String.valueOf(DecimalUtils.convertFenToYuan(capOverdueInfoDTO.getOverdueAmount())));
                        long penaltyAmount = capOverdueInfoDTO.getPenaltyAmount() - capOverdueInfoDTO.getReduAmount() - capOverdueInfoDTO.getPayAmount();
                        result.setPenaltyAmount(String.valueOf(DecimalUtils.convertFenToYuan(penaltyAmount)));
                    }else{
                        BaseLogUtils.error(LOG,"getTemplate","获取逾期信息失败paySchNo:"+dkBillDtlVO.getPaySchNo());
                    }
                }else{
                    BaseLogUtils.error(LOG,"getTemplate","获取垫款单详情失败ruleFlag:"+dkQuestneLogDTO.getRuleFlag());
                }
            }else{
                BaseLogUtils.error(LOG,"getTemplate","获取垫款问卷日志失败questneId:"+questneId);
            }



        }
        return result;
    }

    private String parseDkRstDic(String qtnRstCd) {
        if(qtnRstCd.equals(DkQuestneLogConstant.QTN_RST_CD_1)){
            return "已保存";
        }else if(qtnRstCd.equals(DkQuestneLogConstant.QTN_RST_CD_2)){
            return "预期逾期追加";
        }else if(qtnRstCd.equals(DkQuestneLogConstant.QTN_RST_CD_3)){
            return "预期拖回";
        }else if(qtnRstCd.equals(DkQuestneLogConstant.QTN_RST_CD_4)){
            return "预期还款";
        }else if(qtnRstCd.equals(DkQuestneLogConstant.QTN_RST_CD_5)){
            return "出险严重";
        }else if(qtnRstCd.equals(DkQuestneLogConstant.QTN_RST_CD_6)){
            return "出险其他";
        }else if(qtnRstCd.equals(DkQuestneLogConstant.QTN_RST_CD_7)){
            return "已推送";
        }
        return qtnRstCd;
    }

    @Override
    public List<QuestionVO> getQuestion(String templateCd) {
        List<QuestionVO> result = new ArrayList<>();
        SysScoreIdxQC qc = new SysScoreIdxQC();
        qc.setTmplCd(templateCd);
        qc.setOrderBy("sort_no asc");
        // 查询问题列表
        List<SysScoreIdxDTO> qList = this.idxQueryApiService.searchSysScoreIdxDTOList(qc);
        if(CollectionUtils.isNotEmpty(qList)){
            for (SysScoreIdxDTO qDto : qList) {
                QuestionVO vo = new QuestionVO();
                vo.setQuestion(qDto.getIdxDesc());
                vo.setqNum(qDto.getIdxCd());
                vo.setId(String.valueOf(qDto.getId()));
                // 查询选项
                SysScoreIdxOptQC optQc = new SysScoreIdxOptQC();
                optQc.setTmplIdxId(qDto.getId());
                List<SysScoreIdxOptDTO> optDTOList = this.optQueryApiService.searchSysScoreIdxOptDTOList(optQc);
                List<OptionVO> optList = new ArrayList<>();
                for (SysScoreIdxOptDTO opt : optDTOList) {
                    OptionVO optionVO = new OptionVO();
                    optionVO.setName(opt.getOptDesc());
                    optionVO.setId(String.valueOf(opt.getId()));
                    optionVO.setOptType(opt.getOptTypCd());
                    optList.add(optionVO);
                }
                vo.setOption(optList);
                //  前置条件
                List<SysScoreIdxOptRlDTO> rlDTOList = this.rlQueryApiService.selecListtByIdxCd(String.valueOf(qDto.getId()));
                if(CollectionUtils.isNotEmpty(rlDTOList)){ //如果没有前置条件就会空
                    vo.setHasPre("1");
                    vo.setPreOptList(transfer2KV(rlDTOList));
                }
                result.add(vo);
            }
        }

        return result;
    }

    /**
     *
     * @param rlDTOList
     * @return
     */
    private List<KeyValueVO> transfer2KV(List<SysScoreIdxOptRlDTO> rlDTOList) {
        List<KeyValueVO> res = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(rlDTOList)){
            for (SysScoreIdxOptRlDTO rlDTO : rlDTOList) {
                KeyValueVO vo = new KeyValueVO();
                vo.setKey(String.valueOf(rlDTO.getOptId()));
                vo.setValue(String.valueOf(rlDTO.getIdxCd()));
                res.add(vo);
            }
        }
        return res;
    }

    @Override
    public Long saveRec(String templateId, String templateName, String pkId, String tableName, Long result) {
        SysScoreRecDTO sysScoreRecDTO = new SysScoreRecDTO();
        sysScoreRecDTO.setTmplId(Long.parseLong(templateId));
        sysScoreRecDTO.setTabNm(templateName);
        sysScoreRecDTO.setTabNm(tableName);
        sysScoreRecDTO.setPkId(Long.parseLong(pkId));
        sysScoreRecDTO.setTotScr(result);
        return recAddApiService.add(sysScoreRecDTO);
    }

    @Override
    public void deleteRecDtl(Long recId, String deleteSelection) {
        List<Long> idxList = new ArrayList<>();

        if(StringUtils.isNotBlank(deleteSelection) && recId!= null){
            List<HashMap> selectionMap = JSON.parseArray(deleteSelection, HashMap.class);
            for (HashMap<String,String> hashMap : selectionMap) {
                // 问题id
                String name = hashMap.get("name");
                if(StringUtils.isNotBlank(name)){
                    idxList.add(Long.parseLong(name));
                }
            }
            if(CollectionUtils.isNotEmpty(idxList)){
                dtlRecDeleteApiService.batchDelete(idxList,String.valueOf(recId));
            }
        }
    }
    @Override
    public void saveRecDtl(Long recId, String selection) {
        List list = new ArrayList<SysScoreDtlRecDTO>();
        // 解析json 转化成对象
        if(StringUtils.isNotBlank(selection) && recId!=null){
            List<HashMap> selectionMap = JSON.parseArray(selection, HashMap.class);
            if(CollectionUtils.isNotEmpty(selectionMap)){
                for (HashMap<String,String> hashMap : selectionMap) {
                    // 问题id
                    String name = hashMap.get("name");
                    // 选项id
                    String value1 = hashMap.get("value");
                    SysScoreDtlRecDTO dto = new SysScoreDtlRecDTO();
                    dto.setRecId(recId);
                    dto.setTmplIdxId(Long.parseLong(name));
                    if(StringUtils.isNotBlank(value1)){ //没有值的不add
                        dto.setOptId(Long.parseLong(value1));
                        list.add(dto);
                    }

                }
            }
            // insert list
            if(CollectionUtils.isNotEmpty(list)){
                this.dtlRecAddApiService.addBatch(list);
            }
        }
    }

    @Override
    public SysScoreRecVO selectRecByPkId(Long id) {
        SysScoreRecQC sysScoreRecQC = new SysScoreRecQC();
        sysScoreRecQC.setPkId(id);
        List<SysScoreRecDTO> sysScoreRecDTOS = this.recQueryApiService.searchSysScoreRecDTOList(sysScoreRecQC);
        if(CollectionUtils.isNotEmpty(sysScoreRecDTOS)){
            SysScoreRecDTO sysScoreRecDTO = sysScoreRecDTOS.get(0);
            SysScoreRecVO vo = new SysScoreRecVO();
            vo.setTmplId(sysScoreRecDTO.getTmplId());
            vo.setId(sysScoreRecDTO.getId());
            return vo ;
        }
        return null;
    }

    @Override
    public void assembleAnswer(List<QuestionVO> qList, String id) {
        // 查询评分记录ID
        SysScoreRecVO recVO = this.selectRecByPkId(Long.parseLong(id));
        Long recId = recVO.getId();
        // 查询评分记录明细当中记录的答案
        for (QuestionVO vo : qList) {
            SysScoreDtlRecVO dtlRecVO = this.selectDtlRec(recId, Long.parseLong(vo.getId()));
            if(dtlRecVO != null ){
                vo.setAnswer(dtlRecVO.getOptId());
            }
        }
    }

    @Override
    public SysScoreDtlRecVO selectDtlRec(Long recId, Long qId) {
        SysScoreDtlRecQC sysScoreDtlRecQC = new SysScoreDtlRecQC();
        sysScoreDtlRecQC.setRecId(recId);
        sysScoreDtlRecQC.setTmplIdxId(qId);
        List<SysScoreDtlRecDTO> sysScoreDtlRecDTOS = this.dtlRecQueryApiService.searchSysScoreDtlRecDTOList(sysScoreDtlRecQC);
        if(CollectionUtils.isNotEmpty(sysScoreDtlRecDTOS)){
            SysScoreDtlRecDTO dto = sysScoreDtlRecDTOS.get(0);
            SysScoreDtlRecVO vo = new SysScoreDtlRecVO();
            vo.setOptId(dto.getOptId());
            return vo ;
        }
        return null;
    }

    @Override
    public Long updateRec(String templateId, String templateName, String pkId, String tableName, Long result) {
        // 根据pkid 查询sysScoreRec
        SysScoreRecQC sysScoreRecQC = new SysScoreRecQC();
        sysScoreRecQC.setPkId(Long.parseLong(pkId));
        List<SysScoreRecDTO> sysScoreRecDTOS = this.recQueryApiService.searchSysScoreRecDTOList(sysScoreRecQC);
        SysScoreRecDTO dto =null ;
        if(CollectionUtils.isNotEmpty(sysScoreRecDTOS)){
            dto = sysScoreRecDTOS.get(0);
            dto.setTmplId(Long.parseLong(templateId));
            dto.setTabNm(templateName);
            dto.setTabNm(tableName);
            dto.setPkId(Long.parseLong(pkId));
            dto.setTotScr(result);
            recModifyApiService.modify(dto);
            return dto.getId();
        }
       return null;
    }

    @Override
    public void updateRecDtl(Long recId, String selection) {
        List<Object> updateList =  new ArrayList<>();
        List<Object> addList =  new ArrayList<>();
        // 解析json 转化成对象
        if(StringUtils.isNotBlank(selection) && recId!=null){
            List<HashMap> selectionMap = JSON.parseArray(selection, HashMap.class);
            if(CollectionUtils.isNotEmpty(selectionMap)){
                for (HashMap<String,String> hashMap : selectionMap) {
                    // 问题id
                    String name = hashMap.get("name");
                    // 选项id
                    String value1 = hashMap.get("value");
                    // select DtlRecDto
                    SysScoreDtlRecQC qc = new SysScoreDtlRecQC();
                    qc.setRecId(recId);
                    qc.setTmplIdxId(Long.parseLong(name));
                    List<SysScoreDtlRecDTO> dtos = this.dtlRecQueryApiService.searchSysScoreDtlRecDTOList(qc);
                    if(CollectionUtils.isNotEmpty(dtos)){
                        SysScoreDtlRecDTO dto = dtos.get(0);
                        dto.setOptId(Long.parseLong(value1));
                        updateList.add(dto);
                    }else{
                        // add
                        SysScoreDtlRecDTO dto = new SysScoreDtlRecDTO();
                        dto.setOptId(Long.parseLong(value1));
                        dto.setTmplIdxId(Long.parseLong(name));
                        dto.setRecId(recId);
                        addList.add(dto);
                    }
                }
            }
            // update list
            if(CollectionUtils.isNotEmpty(updateList)){
                dtlRecModifyApiService.modifyBatch(updateList);
            }
            if(CollectionUtils.isNotEmpty(addList)){
                dtlRecAddApiService.addBatch(addList);
            }
        }
    }

    @Override
    public CalculateResult calculateScore(String selection, Integer qtnType) {
        CalculateResult result = new CalculateResult();
        List<KeyValueVO> list = parseJSON2KV(selection);
        ScoreCalculator sc = null ;
        if(qtnType!=null){
            try{
                    //未出险试卷计算
                if(qtnType==0) {
                    sc =   examBScoreCalculator;
                } else if(qtnType==1){ //已出险试卷计算
                    sc = examAScoreCalculator;
                }
            }catch (Exception e){
                BaseLogUtils.error(LOG,"calculateScore","分数计算出错,qtnType="+qtnType+",selection:"+selection);
                throw  e;
            }
        }
        if(sc != null){
            // 计算分数
            result =  sc.cal(list);
        }
        return result;
    }

    @Override
    public Long getValidTemplateId(String s) {
        SysScoreTmplQC sysScoreTmplQC = new SysScoreTmplQC();
        sysScoreTmplQC.setIsValid(1);
        sysScoreTmplQC.setSysCd("11000");
        if("1".equals(s)){ //已出险模板
            sysScoreTmplQC.setpId("dk11000");
        }else{ //未出险
            sysScoreTmplQC.setpId("dk21000");
        }
        List<SysScoreTmplDTO> sysScoreTmplDTOS = this.tmplQueryApiService.searchSysScoreTmplList(sysScoreTmplQC);
        SysScoreTmplDTO dto =null;
        if(CollectionUtils.isNotEmpty(sysScoreTmplDTOS)){
            if(sysScoreTmplDTOS.size()>1){ //记录日志，同一模板出现有多条有效是不对的
                BaseLogUtils.error(LOG,"getValidTemplateId","一类模板只能有一条有效数据！ conditon:"+JSON.toJSONString(sysScoreTmplQC));
            }
            dto=sysScoreTmplDTOS.get(0);
        }else{
            throw new BaseException("查询模板失败，没有查到结果 conditon" +JSON.toJSONString(sysScoreTmplQC));
        }
        if(dto !=null){
            return dto.getId();
        }
        return null;
    }




    /**
     * 把json转化成 list<keyvalue></>
     * @param selection
     * @return
     */
    private List<KeyValueVO> parseJSON2KV(String selection) {
        List<KeyValueVO> resList = new ArrayList<>();
        List<HashMap> hashMaps = JSON.parseArray(selection, HashMap.class);
        for (HashMap<String,String> hashMap : hashMaps) {
            String name = hashMap.get("name");
            String value = hashMap.get("value");
            if(StringUtils.isNotBlank(name) && StringUtils.isNotBlank(value)){
                KeyValueVO vo = new KeyValueVO();
                vo.setKey(name);
                vo.setValue(value);
                resList.add(vo);
            }
        }
        return resList;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext ;
    }
}
